package aaa.schedule;

import java.util.ArrayList;
import java.util.Iterator;

import android.content.Context;

public class GuidScheduleUpdater extends ScheduleUpdater {
	
	protected ArrayList<Lesson> oldLessons ;

	public GuidScheduleUpdater(Context context) {
		super(context) ;
	}// GuidScheduleUpdater()

	/**
	 * Compares the two schedules based on the lesson ids.
	 */
	@Override
	protected void compareS(Schedule oldS, Schedule newS) {
		this.insert.ensureCapacity(newS.getNLessons()) ;
		this.update.ensureCapacity(oldS.getNLessons()) ;
		this.delete.ensureCapacity(oldS.getNLessons()) ;
		this.buildOldIds(oldS) ;
		for(Lesson newLesson : newS) {
			long newId = newLesson.getLessonId() ;
			// lesson is old => guid known
			int indexOf = this.indexOf(newId) ;
			if (indexOf != -1) {
				// lesson is changed => update
				Lesson oldLesson = GuidScheduleUpdater.getLesson(oldS, newId) ;
				if (!oldLesson.equals(newLesson)) {
					this.update.add(newLesson) ;
					newLesson.setType(oldLesson.getType()) ;
				}// if
				this.removeId(indexOf) ;
			} else {
				// lesson is new => guid unknown
				this.insert.add(newLesson) ;
			}// if
		}// for
		// The remaining ids in oldIds have to be removed
		for(Lesson lesson : this.oldLessons) {
			this.delete.add(lesson) ;
		}// for
		this.oldLessons = null ;
	}// compareS(Schedule, Schedule)
	
	protected void buildOldIds(Schedule schedule) {
		this.oldLessons = new ArrayList<Lesson>(schedule.getNLessons()) ;
		if (schedule.getNLessons() == 0) {
			return ;
		}// if
		Iterator<Lesson> iterator = schedule.iterator() ;
		this.oldLessons.add(iterator.next()) ;
		while (iterator.hasNext()) {
			Lesson lesson = iterator.next() ;
//			int insertPosition = this.oldLessons.size() ;
//			this.oldLessons.add(lesson) ;
//			Lesson otherLesson = this.oldLessons.get(insertPosition-1) ;
//			long newId = lesson.getLessonId(), otherId = otherLesson.getLessonId() ;
//			while ((insertPosition > 0) && (otherId > newId)) {
//				this.oldLessons.set(insertPosition, otherLesson) ;
//				insertPosition-- ;
//				otherLesson = this.oldLessons.get(insertPosition-1) ;
//				otherId = otherLesson.getLessonId() ;
//			}// while
//			this.oldLessons.set(insertPosition, lesson) ;
			int insertPosition = this.oldLessons.size() ;
			long lessonId = lesson.getLessonId() ;
			while ((insertPosition > 0) 
					&& (this.oldLessons.get(insertPosition-1).getLessonId() > lessonId)) {
				insertPosition-- ;
			}// while
			this.oldLessons.add(insertPosition, lesson) ;
		}// while
	}// buildOldIds(Schedule)
	
	protected int indexOf (long id) {
		boolean found = false ;
		int left = 0, right = this.oldLessons.size()-1 ;
		int middle = 0 ;
		while ((left <= right) && !found) {
			middle = (left + right) / 2 ;
			long currentId = this.oldLessons.get(middle).getLessonId() ;
			if (currentId == id) {
				found = true ;
			} else if (currentId < id) {
				left = middle+1 ;
			} else/* currentID > id */{
				right = middle-1 ;
			}// if
		}// while
		
		if (found) {
			return middle ;
		}// if
		return -1 ;
	}// isOldId(long)
	
	protected void removeId(int removedPosition) {
		this.oldLessons.remove(removedPosition) ;
	}// removeId(long)
	
	protected static Lesson getLesson(Schedule schedule, long lessonId) {
		for(Lesson lesson : schedule) {
			if (lesson.getLessonId() == lessonId) {
				return lesson ;
			}// if
		}// for
		return null ;
	}// getLesson(Schedule schedule, long)

}// class GuidScheduleUpdater